"""
实际应用示例：结合自定义入参和出参处理
"""
from flask import Blueprint, request
from app.utils.request_validation import validate_json, validate_query_params
from app.utils.response_formatting import success_response, error_response, serialize_response
from app.utils.request_validation import UserRegistrationSchema, UserLoginSchema, UserQuerySchema
from app.utils.response_formatting import UserSchema, UserListSchema
from marshmallow import Schema, fields, validate
from datetime import datetime
import uuid

# 创建示例Blueprint
example_bp = Blueprint("example", __name__, url_prefix="/example")


# 用户注册API - 结合入参验证和出参格式化
@example_bp.route("/register", methods=["POST"])
@validate_json(UserRegistrationSchema)
@serialize_response(schema_class=UserSchema)
def register():
    """用户注册API"""
    data = request.validated_data
    
    # 模拟用户创建逻辑
    new_user = {
        "id": uuid.uuid4().int % 10000,  # 生成随机ID
        "email": data["email"],
        "username": data["username"],
        "is_admin": False,
        "is_active": True,
        "created_at": datetime.now(),
        "updated_at": datetime.now()
    }
    
    # 这里应该保存到数据库
    # db.session.add(new_user)
    # db.session.commit()
    
    return new_user, 201  # 201状态码表示资源创建成功


# 用户登录API
@example_bp.route("/login", methods=["POST"])
@validate_json(UserLoginSchema)
def login():
    """用户登录API"""
    data = request.validated_data
    
    # 模拟用户验证逻辑
    if data["email"] == "admin@example.com" and data["password"] == "password123":
        # 模拟生成JWT令牌
        access_token = f"access_token_{uuid.uuid4().hex}"
        refresh_token = f"refresh_token_{uuid.uuid4().hex}"
        
        return success_response(
            data={
                "access_token": access_token,
                "refresh_token": refresh_token,
                "token_type": "Bearer",
                "expires_in": 3600  # 1小时过期
            },
            message="登录成功"
        ), 200
    else:
        return error_response(
            message="邮箱或密码错误",
            code=401,
            status_code=401
        )


# 获取用户列表API - 结合查询参数验证和分页响应
@example_bp.route("/users", methods=["GET"])
@validate_query_params(UserQuerySchema)
@serialize_response(schema_class=UserListSchema)
def get_users():
    """获取用户列表API"""
    query = request.validated_query
    
    # 模拟获取用户列表逻辑
    page = query["page"]
    per_page = query["per_page"]
    is_active = query.get("is_active")
    search = query.get("search", "")
    
    # 模拟数据库查询
    all_users = [
        {
            "id": 1,
            "email": "user1@example.com",
            "username": "user1",
            "is_admin": False,
            "is_active": True,
            "created_at": datetime.now(),
            "updated_at": datetime.now()
        },
        {
            "id": 2,
            "email": "admin@example.com",
            "username": "admin",
            "is_admin": True,
            "is_active": True,
            "created_at": datetime.now(),
            "updated_at": datetime.now()
        },
        {
            "id": 3,
            "email": "inactive@example.com",
            "username": "inactive_user",
            "is_admin": False,
            "is_active": False,
            "created_at": datetime.now(),
            "updated_at": datetime.now()
        }
    ]
    
    # 应用过滤条件
    filtered_users = all_users
    if is_active is not None:
        filtered_users = [u for u in filtered_users if u["is_active"] == is_active]
    
    if search:
        filtered_users = [
            u for u in filtered_users 
            if search.lower() in u["username"].lower() or search.lower() in u["email"].lower()
        ]
    
    # 计算分页
    total = len(filtered_users)
    start = (page - 1) * per_page
    end = start + per_page
    users = filtered_users[start:end]
    
    pagination = {
        "page": page,
        "per_page": per_page,
        "total": total,
        "pages": (total + per_page - 1) // per_page,
        "has_next": end < total,
        "has_prev": page > 1
    }
    
    return {
        "users": users,
        "pagination": pagination
    }


# 更新用户资料API - 结合路径参数、JSON验证和响应格式化
@example_bp.route("/users/<int:user_id>", methods=["PUT"])
@validate_json(Schema.from_dict({
    "username": fields.Str(validate=validate.Length(min=3, max=80), required=False),
    "email": fields.Email(validate=validate.Length(max=120), required=False),
    "is_active": fields.Bool(required=False)
})())
@serialize_response(schema_class=UserSchema)
def update_user(user_id):
    """更新用户资料API"""
    data = request.validated_data
    
    # 模拟查找用户
    user = {
        "id": user_id,
        "email": "user@example.com",
        "username": "old_username",
        "is_admin": False,
        "is_active": True,
        "created_at": datetime.now(),
        "updated_at": datetime.now()
    }
    
    # 更新用户信息
    if "username" in data:
        user["username"] = data["username"]
    if "email" in data:
        user["email"] = data["email"]
    if "is_active" in data:
        user["is_active"] = data["is_active"]
    
    user["updated_at"] = datetime.now()
    
    # 这里应该保存到数据库
    # db.session.commit()
    
    return user


# 复杂查询API - 多种参数类型和自定义响应格式
@example_bp.route("/search", methods=["GET"])
def advanced_search():
    """高级搜索API - 演示多种参数处理"""
    # 获取查询参数
    query = request.args
    
    # 解析不同类型的参数
    keyword = query.get("keyword", "")
    page = int(query.get("page", 1))
    per_page = min(int(query.get("per_page", 10)), 100)  # 限制最大值
    filters = query.getlist("filters")  # 多值参数
    sort_by = query.get("sort_by", "created_at")
    sort_order = query.get("sort_order", "desc")
    include_inactive = query.get("include_inactive", "false").lower() == "true"
    
    # 参数验证
    if page < 1:
        return error_response(
            message="页码必须大于0",
            code=400
        )
    
    if per_page < 1 or per_page > 100:
        return error_response(
            message="每页数量必须在1-100之间",
            code=400
        )
    
    # 模拟搜索逻辑
    results = [
        {
            "id": i,
            "title": f"搜索结果 {i}",
            "content": f"包含关键词 '{keyword}' 的内容 {i}",
            "author": f"用户{i}",
            "created_at": datetime.now(),
            "relevance": 0.9 - (i * 0.1)
        }
        for i in range(1, 6)
    ]
    
    # 应用排序
    reverse = sort_order == "desc"
    if sort_by == "relevance":
        results.sort(key=lambda x: x["relevance"], reverse=reverse)
    elif sort_by == "created_at":
        results.sort(key=lambda x: x["created_at"], reverse=reverse)
    
    # 应用过滤
    if filters:
        filtered_results = []
        for result in results:
            for filter_item in filters:
                if filter_item == "high_relevance" and result["relevance"] > 0.7:
                    filtered_results.append(result)
                elif filter_item == "recent" and (datetime.now() - result["created_at"]).days < 7:
                    filtered_results.append(result)
        results = filtered_results
    
    # 计算分页
    total = len(results)
    start = (page - 1) * per_page
    end = start + per_page
    paginated_results = results[start:end]
    
    # 自定义响应格式
    return success_response(
        data={
            "results": paginated_results,
            "query": {
                "keyword": keyword,
                "page": page,
                "per_page": per_page,
                "filters": filters,
                "sort_by": sort_by,
                "sort_order": sort_order,
                "include_inactive": include_inactive
            },
            "pagination": {
                "page": page,
                "per_page": per_page,
                "total": total,
                "pages": (total + per_page - 1) // per_page,
                "has_next": end < total,
                "has_prev": page > 1
            }
        },
        message=f"找到 {total} 条结果"
    )


# 文件上传API - 处理文件上传和自定义响应
@example_bp.route("/upload", methods=["POST"])
def upload_file():
    """文件上传API"""
    # 检查是否有文件
    if 'file' not in request.files:
        return error_response(
            message="没有选择文件",
            code=400
        )
    
    file = request.files['file']
    
    # 检查文件名是否为空
    if file.filename == '':
        return error_response(
            message="没有选择文件",
            code=400
        )
    
    # 检查文件类型
    allowed_extensions = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
    if not ('.' in file.filename and 
            file.filename.rsplit('.', 1)[1].lower() in allowed_extensions):
        return error_response(
            message="不支持的文件类型",
            code=400
        )
    
    # 模拟文件保存
    filename = f"saved_{file.filename}"
    file_size = 1024  # 模拟文件大小
    
    # 返回上传结果
    return success_response(
        data={
            "filename": filename,
            "size": file_size,
            "url": f"/uploads/{filename}",
            "uploaded_at": datetime.now().isoformat()
        },
        message="文件上传成功"
    ), 201